/*
* (c) 2014 University of Applied Sciences, Karlsruhe
* Project "Segmentation of depth data of a plenoptic camera"
* summer semester 2014
*
* visualization_3d.h
* Contains a class to manage 3D visualizations (lines, point clouds, etc). This class serves as an interface to the VTK library.
*/

#ifndef _VISUALIZATION_3D_H_
#define _VISUALIZATION_3D_H_

#include <math.h>
#include <string>
#include <cassert>
#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>


#include <pcl/visualization/pcl_visualizer.h>
#include <pcl/visualization/cloud_viewer.h>
#include <pcl/ModelCoefficients.h>

#include "sgBase/misc/color.h"
#include "sgBase/geometrics/line_3d.h"
#include "sgBase/geometrics/point_cloud.h"

using namespace std;

namespace sgBase
{
	/**
	A class to manage a 3D visualization window using VTK. It contains a definable number of rows and columns, where each cell represents a viewport which can
	be used to display data.
	*/
	class Visualization3D
	{
		unsigned int width;		/// The number of viewport column
		unsigned int height;	/// The number of viewport rows

		std::vector<int> viewPortIndices; /// List containing the indices of the VTK viewports, starting from the upper left, first going right, then downwards
	public:
		
		/**
		The PCL viewport used in this window.
		*/
		std::unique_ptr<pcl::visualization::PCLVisualizer> viewer;

		/**
		Constructor.
		*/
		Visualization3D(unsigned int columns, unsigned int rows);

		/**
		Return the VTK viewport ID of a specific cell.
		*/
		int GetViewPortID(unsigned int column, unsigned int row);

		/**
		Adds a point cloud to a viewport.
		\param[in] column The column of the cell.
		\param[in] row The row of the cell.
		\param[in] cloud The point cloud which should be added to the viewport.
		\param[in] pointColorHandler The PCL point cloud color handler, defining the point colorisation method.
		\param[in] title A unique name of the point cloud.
		\return Always zero.
		*/
		int AddPointCloudToViewPort(unsigned int column, unsigned int row, const pcl::PointCloud<pcl::PointXYZRGB>::Ptr &cloud, const pcl::visualization::PointCloudColorHandler<pcl::PointXYZRGB> &pointColorHandler, const string &title);
		
		/**
		Adds a point cloud to a viewport using the colors provided by the point cloud.
		\param[in] column The column of the cell.
		\param[in] row The row of the cell.
		\param[in] cloud The point cloud which should be added to the viewport.
		\param[in] title A unique name of the point cloud.
		\return Always zero.
		*/
		int AddPointCloudToViewPort(unsigned int column, unsigned int row, const pcl::PointCloud<pcl::PointXYZRGB>::Ptr &cloud, const string &title);
		
		/**
		Adds a point cloud to a viewport painting all points in the same color.
		\param[in] column The column of the cell.
		\param[in] row The row of the cell.
		\param[in] cloud The point cloud which should be added to the viewport.
		\param[in] title A unique name of the point cloud.
		\param[in] color The color of the point cloud.
		\return Always zero.
		*/
		int AddPointCloudToViewPort(unsigned int column, unsigned int row, const pcl::PointCloud<pcl::PointXYZRGB>::Ptr &cloud, const string &title, const Color &color);
		
		/**
		Adds a line to a viewport.
		\param[in] column The column of the cell.
		\param[in] row The row of the cell.
		\param[in] line The line which is to be added to the viewport.
		\param[in] title A unique name of the line.
		\param[in] color The color of the line.
		\return Always zero.
		*/
		int AddLineToViewPort(unsigned int column, unsigned int row, const Line3D &line, const string &title, const Color &color);
	};
}
#endif